home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 49
/
Amiga Format CD49 (2000-01-17)(Future Publishing)(GB)(Track 1 of 3)[!][issue 2000-02].iso
/
-in_the_mag-
/
program_perfection
/
text.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-12-08
|
6KB
|
295 lines
/*
* text.c
*
* Text class
*
* $Id :$
* $Log:$
*
*/
#include "defs.h"
#include "lines.h"
#include "text.h"
#include "memory.h"
#include <clib/alib_protos.h>
static LINE_PTR add_line( TEXT_PTR text, const STRPTR line_start, const STRPTR line_end, ERROR_TYPE *err );
/*******************************************************************/
/*
* Text_New()
*
* PURPOSE: Constructor for text class
*
* INPUTS :
*
* RETURNS:
*/
TEXT_PTR
Text_New( const STRPTR contents, ERROR_TYPE *err_code )
{
TEXT_PTR new_text;
if( new_text = (TEXT_PTR) Memory_Alloc( sizeof( TEXT_TYPE ) ) )
{
NewList( (struct List *) &(new_text->Contents) );
{
STRPTR current_char = contents;
STRPTR line_start = contents;
for( ; *current_char; current_char++ )
{
switch( *current_char )
{
case '\n' :
case '\f' :
/* found a line break */
if( add_line( new_text, line_start, current_char + 1, err_code ) )
line_start = current_char + 1;
else
;
default:
/* do nothing */
}
} /* for */
if( current_char != line_start )
{
/* the last line didn't end in a break - so add it now */
add_line( new_text, line_start, current_char + 1, err_code );
}
} /* block */
} /* if */
else
*err_code = ERR_NO_MEMORY;
return new_text;
}
/*
* add_line()
*
* PURPOSE: add a line to a text object and bump line count
*
* INPUTS : text - the text object
* line_start - ptr to start of line
* line_end - ptr to end of line
*
* RETURNS: ptr to the new line if succcesful, NULL otherwise
*
*/
static LINE_PTR
add_line( TEXT_PTR text, const STRPTR line_start, const STRPTR line_end, ERROR_TYPE *err_code )
{
LINE_PTR new_line = NULL;
/* is the list full? */
if( text->Length < MAX_TEXT_LEN )
{
/* nope, still room */
LINE_LEN_TYPE len = line_end - line_start;
if( new_line = Line_New( line_start, len, err_code ) )
{
AddTail( (struct List *) &(text->Contents), (struct Node *) &(new_line->Node) );
text->Length++;
if( len > text->MaxWidth ) text->MaxWidth = len;
}
}
else
/* */
*err_code = ERR_TOO_MANY_LINES;
return new_line;
}
/*******************************************************************/
/*
* Text_Dispose()
*
* PURPOSE: Destructor for text class
*
* INPUTS:
*
* RETURNS: None
*/
VOID
Text_Dispose( TEXT_PTR text )
{
LINE_PTR l1 = (LINE_PTR) text->Contents.mlh_Head;
LINE_PTR l2;
TEXT_LEN_TYPE i = text->Length;
for( ; i; i-- )
{
l2 = (LINE_PTR) l1->Node.mln_Succ;
Line_Dispose( l1 );
l1 = l2;
}
Memory_Free( text, sizeof( TEXT_TYPE ) );
}
/*******************************************************************/
/*
* Text_GetTopLine()
*
* PURPOSE:
*
* INPUTS :
*
* RETURNS:
*/
LINE_PTR
Text_GetTopLine( const TEXT_PTR text )
{
return text->Length ? (LINE_PTR) text->Contents.mlh_Head : NULL;
}
/*******************************************************************/
/*
* Text_GetBottomLine()
*
* PURPOSE:
*
* INPUTS :
*
* RETURNS:
*/
LINE_PTR
Text_GetBottomLine( const TEXT_PTR text )
{
return text->Length ? (LINE_PTR) text->Contents.mlh_TailPred : NULL;
}
/*******************************************************************/
/*
* Text_GetNextLine()
*
* PURPOSE: Get next Line in a linked list of Line objects.
*
* INPUTS : line - the Line to find the successor of.
*
* RETURNS: pointer to the sucessor if there is one, else NULL
*/
LINE_PTR
Text_GetNextLine( const TEXT_PTR text, const LINE_PTR line )
{
LINE_PTR l = (LINE_PTR) line->Node.mln_Succ;
return (l->Node.mln_Succ) ? l : NULL;
}
/*******************************************************************/
/*
* Text_GetPrevLine()
*
* PURPOSE: Get previous Line in a linked list of Line objects.
*
* INPUTS : line - the Line to find the predecessor of.
*
* RETURNS: pointer to the predecessor if there is one, else NULL
*/
LINE_PTR
Text_GetPrevLine( const TEXT_PTR text, const LINE_PTR line )
{
LINE_PTR l = (LINE_PTR) line->Node.mln_Pred;
return l->Node.mln_Pred ? l : NULL;
}
/*******************************************************************/
/*
* Text_GetNthLine()
*
* PURPOSE:
*
* INPUTS :
*
* RETURNS:
*/
LINE_PTR
Text_GetNthLine( const TEXT_PTR text, TEXT_LEN_TYPE line_no )
{
LINE_PTR line = NULL;
if( line_no < text->Length )
{
LINE_LEN_TYPE i = 0;
line = (LINE_PTR) text->Contents.mlh_Head;
while( i++ < line_no )
line = (LINE_PTR) line->Node.mln_Succ;
}
return line;
}
/*******************************************************************/
/*
* Text_GetLength()
*
* PURPOSE:
*
* INPUTS :
*
* RETURNS:
*/
TEXT_LEN_TYPE
Text_GetNoOfLines( const TEXT_PTR text )
{
return text->Length;
}
/*******************************************************************/
/*
* Text_GetMaxWidth()
*
* PURPOSE:
*
* INPUTS :
*
* RETURNS:
*/
LINE_LEN_TYPE
Text_GetMaxWidth( const TEXT_PTR text )
{
return text->MaxWidth;
}